package com.fyy.java8.strwam;

import com.fyy.java8.methodRef.User;
import com.fyy.java8.methodRef.UserData;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author fyy
 * @Description Stream Api测试
 * @Date 2021/2/26 14:56
 */
public class StreamApiTest {

    /** 切片与筛选 */
    public static void test1(){
        List<User> list = UserData.getUsersData();
        //filter(Predicate p) 筛选
        list.stream().filter(u -> Integer.parseInt(u.getAge()) > 300).forEach(System.out::println);
        //distinct() 去重
        list.stream().distinct().forEach(System.out::println);
        //limit(long maxSize) 切片,截取流的前几个元素
        list.stream().limit(2).forEach(System.out::println);
        //skip(long n) 切片,跳过流的前n个元素
        list.stream().skip(2).forEach(System.out::println);
    }

    /** 映射 */
    public static void test2(){
        //map(Function f) 遍历每个元素,并将其映射成一个新的元素
        List<String> list = Arrays.asList("20", "1", "2", "3");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
        //mapToInt(ToIntFunction f);
        list.stream().mapToInt(str -> Integer.parseInt(str)).forEach(System.out::println);

        //flatMap(Function f) 流中的每个值都被换成另一个流，然后把所有流连接成一个流
        list.stream().flatMap(StreamApiTest::fromStrToStream).forEach(System.out::println);
        //对比map方法实现
        Stream<Stream<Character>> streamStream = list.stream().map(StreamApiTest::fromStrToStream);
        streamStream.forEach(s -> {
            s.forEach(System.out::println);
        });

    }

    public static Stream<Character> fromStrToStream(String str){
        ArrayList<Character> list = new ArrayList<>();
        for(Character c :str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }

    /** 排序 */
    public static void test3(){
        List<User> list = UserData.getUsersData();
        List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5, 6);
        //自然顺序排序
        list1.stream().sorted().forEach(System.out::println);
        //按比较器顺序排序,对象排序需要是实现Comparator接口或者如下
        list.stream().sorted((u1,u2) -> Integer.compare(Integer.parseInt(u1.getAge()),Integer.parseInt(u2.getAge()))).forEach(System.out::println);
    }

    /** 匹配与查找 */
    public static void test4(){
        List<User> list = UserData.getUsersData();
        //allMatch(Predicate p):断定型判断，返回布尔类型，流中是否所有用户都是50岁以上
        boolean b = list.stream().allMatch(u -> Integer.parseInt(u.getAge()) > 50);
        //anyMatch(Predicate p):断定型判断，返回布尔类型，流中是否存在用户是50岁以上
        boolean b1 = list.stream().anyMatch(u -> Integer.parseInt(u.getAge()) > 50);
        //anyMatch(Predicate p):断定型判断，返回布尔类型，流中是否不存在用户是50岁以上
        boolean b2 = list.stream().noneMatch(u -> Integer.parseInt(u.getAge()) > 50);
        //findFirst():返回第一个元素
        Optional<User> u = list.stream().findFirst();
        //findAny():返回任一个元素
        Optional<User> u1 = list.stream().findAny();
        //count():统计总数
        long count = list.stream().count();
        //max(Comparator c):返回流中最大值
        Optional<User> maxUser = list.stream().max((o1, o2) -> Integer.compare(Integer.parseInt(o1.getAge()), Integer.parseInt(o2.getAge())));
        //min(Comparator c):返回流中最小值
        Optional<User> minUser = list.stream().min((o1, o2) -> Integer.compare(Integer.parseInt(o1.getAge()), Integer.parseInt(o2.getAge())));
        //forEach(Consumer c):内部迭代
        list.stream().forEach(System.out::println);
    }

    /** 归约 */
    public static void test5(){
        //reduce(T iden, BinaryOperator b):计算总和
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer reduce = list.stream().reduce(0, Integer::sum);
        //reduce(BinaryOperator b):计算所有用户的总年龄
        List<User> uList = UserData.getUsersData();
        Optional<User> reduce1 = uList.stream().reduce((u1, u2) -> new User("", Integer.parseInt(u1.getAge()) + Integer.parseInt(u2.getAge())+""));
        //reduce(BinaryOperator b):计算所有用户的总年龄2--->map-reduce
        OptionalInt reduce2 = uList.stream().mapToInt(u -> Integer.parseInt(u.getAge())).reduce(Integer::sum);
    }

    /** 收集 */
    public static void test6(){
        List<User> uList = UserData.getUsersData();
        //不使用collector返回的是一个流
        Stream<User> userStream = uList.stream().filter(u -> Integer.parseInt(u.getAge()) > 50);
        //使用collector返回的是一个List
        List<User> users = uList.stream().filter(u -> Integer.parseInt(u.getAge()) > 50).collect(Collectors.toList());
    }

}
